﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using QRCodePass.Core;
using QRCodePass.Core.Extensions;
using QRCodePass.Core.Models;
using QRCodePass.Core.Models.EnumTypes;
// ReSharper disable ConvertToUsingDeclaration

namespace QRCodePass.EntityFrameworkCore.Seed
{
    /// <summary>
    /// 数据初始化
    /// </summary>
    public static class DataInitializer
    {
        public static IApplicationBuilder UseDataInitializer(
            this IApplicationBuilder builder)
        {
            using (var scope = builder.ApplicationServices.CreateScope())
            {
                var dbContext = scope.ServiceProvider.GetService<AppDbContext>();
                var userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>();
                var roleManager = scope.ServiceProvider.GetService<RoleManager<IdentityRole>>();

                #region 系部种子数据
                if (dbContext.Departments.Any())
                {
                    return builder; // 数据已经初始化了。
                }
                var departments = new[] {
                    new Department { Name = "信息工程系"},
                    new Department { Name = "资源工程系" },
                    new Department { Name = "土木工程系"},
                    new Department { Name = "管理工程系"}
                };

                foreach (var d in departments)
                    dbContext.Departments.Add(d);
                dbContext.SaveChanges();
                #endregion


                #region 楼栋的种子数据
                if (dbContext.Build.Any())
                {
                    return builder; // 数据已经初始化了。
                }
                var builds = new[] {
                    new Build {Name="图书馆",BuildAddress =  "大门前进入", Description = "备注" },
                    new Build {Name="一教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="二教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="三教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="四教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="五教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="六教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="七教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="八教学楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="求真楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="求实楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="崇善楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="崇美楼",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="玉兰苑",BuildAddress =  "地理位置", Description = "备注" },
                    new Build {Name="丹桂苑",BuildAddress =  "地理位置", Description = "备注" }
                };

                foreach (var o in builds)
                    dbContext.Build.Add(o);
                dbContext.SaveChanges();
                #endregion

                #region 学生种子信息

                if (dbContext.Students.Any())
                {
                    return builder; // 数据已经初始化了。
                }

                var students = new[] {
                    new Student { Name = "张三", Major = MajorEnum.ComputerScience, Email = "zhangsan@shewai.com", EnrollmentDate = DateTime.Parse ("2021-09-01"), BuildId = builds.Single(x=>x.Name=="丹桂苑").Id, DepartmentId = departments.Single(x=>x.Name=="信息工程系").Id, Pwd =AESEncryptExtension.AesEncrypt("123456"),StudentNo = "192300410"},
                    new Student { Name = "李四", Major = MajorEnum.Mathematics, Email = "lisi@shewai.com", EnrollmentDate = DateTime.Parse ("2017-09-01") , BuildId =  builds.Single(x=>x.Name=="丹桂苑").Id, DepartmentId = departments.Single(x=>x.Name=="信息工程系").Id, Pwd =AESEncryptExtension.AesEncrypt("123456"),StudentNo = "192300411"},
                    new Student { Name = "王五", Major = MajorEnum.ElectronicCommerce, Email = "wangwu@shewai.com", EnrollmentDate = DateTime.Parse ("2012-09-01"), BuildId =  builds.Single(x=>x.Name=="丹桂苑").Id, DepartmentId = departments.Single(x=>x.Name=="信息工程系").Id, Pwd = AESEncryptExtension.AesEncrypt("123456") ,StudentNo = "192300412"},
                    new Student { Name = "赵柳", Major = MajorEnum.None, Email = "zhaoliu@shewai.com", EnrollmentDate = DateTime.Parse ("2012-09-01"), BuildId =  builds.Single(x=>x.Name=="玉兰苑").Id, DepartmentId = departments.Single(x=>x.Name=="信息工程系").Id, Pwd = AESEncryptExtension.AesEncrypt("123456") ,StudentNo = "192300413"}
                };
                foreach (Student item in students)
                {
                    dbContext.Students.Add(item);
                }
                dbContext.SaveChanges();

                #endregion 


                #region 流程种子数据

                if (dbContext.Processes.Any())
                {
                    return builder; // 数据已经初始化了。
                }
                var processes = new[] {

                    new Process {Id=1,ProcName = "学籍注册",           PreTask = 1,BuildId=builds.Single(x=>x.Name=="图书馆").Id,Description="描述"},
                    new Process {Id=2,ProcName = "班主任处报道",       PreTask = 1,BuildId=builds.Single(x=>x.Name=="图书馆").Id,Description="描述"},
                    new Process {Id=3,ProcName = "宿舍楼领取钥匙",     PreTask = 2,BuildId=builds.Single(x=>x.Name=="图书馆").Id,Description="描述"},
                    new Process {Id=4,ProcName = "军训服装领取",       PreTask = 3,BuildId=builds.Single(x=>x.Name=="图书馆").Id,Description="描述"},
                    new Process {Id=5,ProcName = "校园卡办理",         PreTask = 4,BuildId=builds.Single(x=>x.Name=="图书馆").Id,Description="描述"},
                    new Process {Id=6,ProcName = "热水门禁一卡通办理", PreTask = 5,BuildId=builds.Single(x=>x.Name=="图书馆").Id,Description="描述"}
                };

                foreach (var c in processes)
                    dbContext.Processes.Add(c);
                dbContext.SaveChanges();

                #endregion 

                #region 报道记录种子数据

                var processRecord = new[] {
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "学籍注册").Id, StudentId = students.Single (i => i.Name == "张三").Id,RecordTime=DateTime.Parse("2021/3/29 9:54"),RecordPerson="SuperAdmin"},
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "学籍注册").Id, StudentId = students.Single (i => i.Name == "李四").Id,RecordTime=DateTime.Parse("2021/3/29 9:54"),RecordPerson="SuperAdmin"},
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "学籍注册").Id, StudentId = students.Single (i => i.Name == "王五").Id,RecordTime=DateTime.Parse("2021/3/29 9:54"),RecordPerson="SuperAdmin"},
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "学籍注册").Id, StudentId = students.Single (i => i.Name == "赵柳").Id,RecordTime=DateTime.Parse("2021/3/29 9:54"),RecordPerson="SuperAdmin"},
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "班主任处报道").Id, StudentId = students.Single (i => i.Name == "张三").Id ,RecordTime=DateTime.Parse("2021/3/29 10:54"),RecordPerson="SuperAdmin"},
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "班主任处报道").Id, StudentId = students.Single (i => i.Name == "李四").Id ,RecordTime=DateTime.Parse("2021/3/29 10:54"),RecordPerson="SuperAdmin"},
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "班主任处报道").Id, StudentId = students.Single (i => i.Name == "王五").Id ,RecordTime=DateTime.Parse("2021/3/29 10:54"),RecordPerson="SuperAdmin"},
                    new StudentProcess {ProcessId = processes.Single (c => c.ProcName == "班主任处报道").Id, StudentId = students.Single (i => i.Name == "赵柳").Id ,RecordTime=DateTime.Parse("2021/3/29 10:54"),RecordPerson="SuperAdmin"}

                };

                foreach (var sp in processRecord)
                    dbContext.StudentProcess.Add(sp);
                dbContext.SaveChanges();

                #endregion

                #region 系部与流程关联种子数据

                var departProcs = new[] {
                    new DepartProc { ProcessId = processes.Single (s => s.ProcName == "学籍注册").Id,       DepartmentId = departments.Single (c => c.Name == "信息工程系").Id},
                    new DepartProc { ProcessId = processes.Single (s => s.ProcName == "班主任处报道").Id,   DepartmentId = departments.Single (c => c.Name == "信息工程系").Id},
                    new DepartProc { ProcessId = processes.Single (s => s.ProcName == "宿舍楼领取钥匙").Id, DepartmentId = departments.Single (c => c.Name == "信息工程系").Id},
                    new DepartProc { ProcessId = processes.Single (s => s.ProcName == "军训服装领取").Id,   DepartmentId = departments.Single (c => c.Name == "信息工程系").Id},
                    new DepartProc { ProcessId = processes.Single (s => s.ProcName == "校园卡办理").Id,     DepartmentId = departments.Single (c => c.Name == "信息工程系").Id},
                    new DepartProc { ProcessId = processes.Single (s => s.ProcName == "热水门禁一卡通办理").Id, DepartmentId = departments.Single (c => c.Name == "信息工程系").Id}

                };
                foreach (var sc in departProcs)
                    dbContext.DepartProc.Add(sc);
                dbContext.SaveChanges();

                #endregion 

                #region 用户种子数据

                if (dbContext.Users.Any())
                {
                    return builder; // 数据已经初始化了。
                }

                List<int> procList = new List<int>();//包含的流程Id
                foreach (var process in processes)
                {
                    procList.Add(process.Id);
                }
                string procListStr = String.Join(",", procList.ConvertAll<string>(m => m.ToString()).ToArray());
                var user = new ApplicationUser { Email = "superadmin@sw.com", UserName = "superadmin@sw.com", EmailConfirmed = true, City = "上海", ProcessList = procListStr ,RealName="超级管理员"};
                userManager.CreateAsync(user, "kxabc5740").Wait(); // 等待异步方法执行完毕
                dbContext.SaveChanges();
                var adminRole = "SuperAdmin";

                var role = new IdentityRole { Name = adminRole };

                roleManager.CreateAsync(role);

                dbContext.UserRoles.Add(new IdentityUserRole<string>
                {
                    RoleId = role.Id,
                    UserId = user.Id
                });
                dbContext.SaveChanges();

                #endregion 用户种子数据
            }

            return builder;
        }
    }
}